package nix.bs.dao;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import nix.bs.domain.Book;
import nix.bs.domain.Order;
import nix.bs.domain.OrderItem;
import nix.commons.CommonUtils;
import nix.jdbc.TxQueryRunner;

import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.BeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.RowProcessor;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

public class OrderDao {

	private QueryRunner qr = new TxQueryRunner();

	public void add(Order order) {
		try {
			// util转为sql
			Timestamp ordertime = new Timestamp(order.getOrdertime().getTime());
			Object[] params = new Object[] { order.getOid(), ordertime,
					order.getTotal(), order.getState(),
					order.getOwner().getUid(), order.getAddress() };
			qr.update(
					"insert into tb_orders (oid, ordertime, total, state, uid, address) values (?, ?, ?, ?, ?, ?)",
					params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public void addOrderItemList(List<OrderItem> orderItemList) {
		try {
			Object[][] params = new Object[orderItemList.size()][];
			for (int i = 0; i < orderItemList.size(); i++) {
				OrderItem item = orderItemList.get(i);
				params[i] = new Object[] { item.getIid(), item.getCount(),
						item.getSubtotal(), item.getOrder().getOid(),
						item.getBook().getBid() };
			}
			// 批处理
			qr.batch(
					"insert into tb_orderitem (iid, count, subTotal, oid, bid) values (?, ?, ?, ?, ?)",
					params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	// 通过uid查询List<Order>
	public List<Order> findByUid(String uid) {
		try {
			List<Order> orderList = qr.query(
					"select * from tb_orders where uid = ?",
					new BeanListHandler<Order>(Order.class), uid);
			for (Order order : orderList) {
				loadOrderItems(order);
			}
			return orderList;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	// 加载Order中的OrderItem
	private void loadOrderItems(Order order) {
		try {
			// 使用MapListHandler()查询两张表的结果集，Map为列，List为行
			List<Map<String, Object>> mapList = qr
					.query("select * from tb_orderitem i, tb_book b where i.bid = b.bid and i.oid = ?",
							new MapListHandler(), order.getOid());
			List<OrderItem> orderItemList = addOrderItemList(mapList);
			order.setOrderItemList(orderItemList);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	// 将List<Map>转换为List<OrderItem>
	private List<OrderItem> addOrderItemList(List<Map<String, Object>> mapList) {
		List<OrderItem> orderItemList = new ArrayList<OrderItem>();
		for (Map<String, Object> map : mapList) {
			OrderItem orderItem = toOrderItem(map);
			orderItemList.add(orderItem);
		}
		return orderItemList;
	}

	// 将Map转换为OrderItem
	private OrderItem toOrderItem(Map<String, Object> map) {
		OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class);
		Book book = CommonUtils.toBean(map, Book.class);
		orderItem.setBook(book);
		return orderItem;
	}

	public Order findByOid(String oid) {
		try {
			Order order = qr.query("select * from tb_orders where oid = ?",
					new BeanHandler<Order>(Order.class), oid);
			loadOrderItems(order);
			return order;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public int getStateByOid(String oid) {
		try {
			return (Integer) qr.query(
					"select state from tb_orders where oid = ?",
					new ScalarHandler(), oid);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public void updateState(String oid, int state) {
		try {
			qr.update("update tb_orders set state = ? where oid = ?", state,
					oid);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public List<Order> findAll() {
		try {
			List<Order> orderList = qr.query("select * from tb_orders",
					new BeanListHandler<Order>(Order.class));
			for (Order order : orderList) {
				loadOrderItems(order);
			}
			return orderList;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public List<Order> findByState(int state) {
		try {
			List<Order> orderList = qr.query(
					"select * from tb_orders where state = ?",
					new BeanListHandler<Order>(Order.class), state);
			for (Order order : orderList) {
				loadOrderItems(order);
			}
			return orderList;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}
